﻿using Newtonsoft.Json;
using Newtonsoft.Json.Converters;
using System;
using System.Collections.Generic;
using System.Data;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Web;
using System.Security.Cryptography;
using System.Text.RegularExpressions;
using System.Xml;

namespace Youz.Common.Helper
{
    public class CommonHelper
    {
        /// <summary>
        /// 上传文件格式
        /// </summary>
        public static string[] ext = { ".png", ".jpg", ".jpeg" };//实名认证 去除 , ".gif"

        /// <summary>
        /// 返回标准时间 
        /// </sumary>
        public static string GetStandardDateTime(string fDateTime, string formatStr)
        {
            if (fDateTime == "0000-0-0 0:00:00")
            {
                return fDateTime;
            }
            DateTime s = Convert.ToDateTime(fDateTime);
            return s.ToString(formatStr);
        }

        /// <summary>
        /// 时间字符串转时间戳
        /// </summary>
        /// <param name="dateTimeString"></param>
        /// <returns></returns>
        public static string GetUNIXTime(DateTime dateTime)
        {
            var epoch = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc);
            var data = (dateTime - epoch).TotalMilliseconds.ToString();

            return data;
        }

        /// <summary>
        /// 时间字符串转时间戳
        /// </summary>
        /// <param name="dateTimeString"></param>
        /// <returns></returns>
        public static string GetUNIXTime(string dateTimeString)
        {
            return GetUNIXTime(DateTime.Parse(dateTimeString));
        }

        public static DateTime ConvertUNIXTime(double d)
        {
            var unix = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc);
            var time = unix.AddMilliseconds(d);
            return time;
        }

        public static string FormatMemberAccount(string memberaccount)
        {
            if (string.IsNullOrWhiteSpace(memberaccount)) return string.Empty;
            else return memberaccount.Substring(0, 1) + "*****" + memberaccount.Substring(memberaccount.Length - 1, 1);
        }

        /// <summary>
        /// 前台站點SHA512加密
        /// </summary>
        /// <param name="text">明文</param>
        /// <returns></returns>
        public static string GetSHA512(string text)
        {
            SHA512 sha512 = new SHA512CryptoServiceProvider();      //建立一个SHA512
            byte[] source = Encoding.Default.GetBytes(text);        //将字符串转为Byte[]
            byte[] crypto = sha512.ComputeHash(source);             //进行SHA512加密
            return Convert.ToBase64String(crypto);         //把加密后的字符串从Byte[]转为字符串
        }

        /// <summary>
        /// MD5加密 + 随机数2位 (用于生成会员ID)
        /// </summary>
        /// <param name="text">明文</param>
        /// <returns></returns>
        public static string GetMD5(string text)
        {
            System.Security.Cryptography.MD5CryptoServiceProvider MD5 = new System.Security.Cryptography.MD5CryptoServiceProvider();
            byte[] encryptedBytes = MD5.ComputeHash(System.Text.Encoding.ASCII.GetBytes(text));
            StringBuilder sb = new StringBuilder();
            for (int i = 0; i < encryptedBytes.Length; i++)
            {
                sb.AppendFormat("{0:x2}", encryptedBytes[i]);
            }
            return sb.ToString().ToLower();
        }

        /// <summary>
        /// 获得DataSet中的DataTable
        /// </summary>
        /// <param name="ds"></param>
        /// <returns></returns>
        public static DataTable GetDateTable(DataSet ds)
        {
            if (ds == null || ds.Tables.Count == 0)
            {
                return null;
            }

            return ds.Tables[0];
        }

        public static DataRow GetDataRow(DataTable dt)
        {
            if (dt == null || dt.Rows.Count == 0)
            {
                return null;
            }

            return dt.Rows[0];
        }

        /// <summary>
        /// 获得DataSet中的第一行数据
        /// </summary>
        /// <param name="ds"></param>
        /// <returns></returns>
        public static DataRow GetDataRow(DataSet ds)
        {
            DataTable dt = GetDateTable(ds);

            return GetDataRow(dt);
        }

        /// <summary>
        /// 判断是否为Ajax请求
        /// </summary>
        /// <returns></returns>
        public static bool IsAjaxRequest()
        {
            String requestType = HttpContext.Current.Request.Headers["X-Requested-With"];
            if (requestType != null && requestType.ToLower().Equals("xmlhttprequest"))
            {
                return true;
            }
            else
            {
                return false;
            }
        }

        /// <summary>
        /// 文件上传
        /// </summary>
        /// <param name="file"></param>
        /// <param name="filePackage"></param>
        /// <returns>返回文件的存储路径</returns>
        public static string UpLoadFile(HttpPostedFile file, string filePackage = "")
        {
            string savePath = "";
            if ((file != null && file.ContentLength > 0))
            {
                string fileExtension = Path.GetExtension(file.FileName).ToLower();
                if (ext.Contains(fileExtension))
                {
                    string filename = DateTime.Now.Ticks + Path.GetExtension(file.FileName);
                    string dir = string.Empty;
                    string fullDir = UrlHelper.GetUploadFullPath(out dir);

                    file.SaveAs(fullDir + filename);
                    savePath = dir + filename;
                }
                else
                {
                    savePath = "-1";
                }
            }
            return savePath;
        }

        /// <summary>
        /// 上传Base64字符串为图片
        /// </summary>
        /// <param name="base64"></param>
        /// <param name="filePackage"></param>
        /// <returns></returns>
        public static string UpLoadBase64Img(string base64, string filePackage = "")
        {
            if (!String.IsNullOrEmpty(base64) && base64.Length > 23)
            {
                string filename = DateTime.Now.Ticks + ".jpg";
                string relativePath = string.Empty;
                string fullPath = UrlHelper.GetUploadFullPath(out relativePath) + filename;

                ImageHelper.SaveBase64ToImage(base64, fullPath);

                return relativePath + filename;
            }
            else
            {
                return string.Empty;
            }
        }
        
        /// <summary>
        /// 獲取日期範圍查詢的SQL代碼
        /// </summary>
        /// <param name="strStartDate"></param>
        /// <param name="strEndDate"></param>
        /// <param name="dateSqlQueryColumn"></param>
        /// <returns></returns>
        public static string GetDateQuerySql(string strStartDate, string strEndDate, string dateSqlQueryColumn)
        {
            StringBuilder str = new StringBuilder();
            DateTime startDate, endDate;
            bool isStartDate = false, isEndDate = false;
            if (DateTime.TryParse(strStartDate, out startDate))
            {
                isStartDate = true;
            }
            if (DateTime.TryParse(strEndDate, out endDate))
            {
                endDate = endDate.AddDays(1);
                isEndDate = true;
            }

            if (isStartDate && isEndDate)
            {
                str.AppendFormat(" and {0} >= '{1}' and {0} < '{2}'", dateSqlQueryColumn, startDate.ToShortDateString(), endDate.ToShortDateString());
            }
            else if (isStartDate)
            {
                str.AppendFormat(" and {0} >= '{1}'", dateSqlQueryColumn, startDate.ToShortDateString());
            }
            else if (isEndDate)
            {
                str.AppendFormat(" and {0} < '{1}'", dateSqlQueryColumn, endDate.ToShortDateString());
            }

            return str.ToString();
        }

        #region 重置密码时随机生成密码
        private static string strUppercase = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
        private static string strAll = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
        public static string RandomPwd()
        {
            string result = "";
            Random random = new Random();
            for (int i = 0; i < 8; i++)
            {
                int rd = 0;
                string oneChar = string.Empty;
                if (i == 0)
                {
                    rd = random.Next(26);
                    oneChar = strUppercase.Substring(rd, 1);
                }
                else
                {
                    //返回一个小于62的int类型的随机数
                    rd = random.Next(62);
                    //随机从指定的位置开始获取一个字符
                    oneChar = strAll.Substring(rd, 1);
                }
                result += oneChar;
            }
            return result;
        }
        #endregion

        #region 字符串截取
        #region 截取允许的最大的字符串子串
        /// <summary>
        /// 说明：截取允许的最大的字符串子串       
        /// </summary>
        /// <param name="str">要截取的字符串</param>
        /// <param name="len">保留的长度</param>
        /// <param name="postStr">如果超过允许的长度，字符串添加的后缀</param>
        /// <returns></returns>
        public static string GetSubString(string str, int len, string postStr)
        {
            if (!string.IsNullOrEmpty(str))
            {
                string subStr = MaxLengthSubString(str, len);
                int subStrLen = GetStringLength(subStr);
                int postStrLen = GetStringLength(postStr);
                if (subStr.Length == str.Length)
                {
                    return str;
                }
                else
                {
                    if (subStrLen > postStrLen)
                    {
                        return MaxLengthSubString(subStr, len - postStrLen) + postStr;
                    }
                    else
                    {
                        return subStr;
                    }
                }
            }
            else
            {
                return "";
            }
        }
        #endregion
        #region 截取允许的最大的字符串子串

        /// <summary>
        /// 说明：截取允许的最大的字符串子串      
        /// </summary>
        /// <param name="str">要截取的字符串</param>
        /// <param name="len">保留的长度</param>
        /// <returns></returns>
        public static string MaxLengthSubString(string str, int len)
        {
            string temp = str;

            if (GetStringLength(str) <= len)
            {
                return str;
            }
            else
            {
                //先大胆截断一截

                if (str.Length > len)
                {
                    temp = str.Substring(0, len);
                }

                while (GetStringLength(temp) > len && temp.Length > 0)
                {
                    temp = temp.Substring(0, temp.Length - 1);
                }

                return temp;
            }
        }
        #endregion
        #region 获取字符串长度

        /// <summary>
        /// 说明：获取字符串长度       
        /// </summary>
        /// <param name="str"></param>
        /// <returns></returns>
        public static int GetStringLength(string str)
        {
            if (!string.IsNullOrEmpty(str))
            {
                return Regex.Replace(str, "[\u4e00-\u9fa5]", "zz", RegexOptions.IgnoreCase).Length;
            }
            else
            {
                return 0;
            }
        }
        #endregion

        /// <summary>
        /// 截取字符串 只显示后4位
        /// </summary>
        /// <returns></returns>
        public static string CodeSub(string code)
        {
            if (code.Length < 4)
            {
                return code;
            }
            string ID = string.Empty;
            //   ID += code.Substring(0, 4);
            ID += "****";
            ID += code.Substring(code.Length - 4, 4);
            return ID;

        }
        #endregion

        /// <summary>
        /// DataTable中的数据导出到Excel并下载
        /// </summary>
        /// <param name="dt">要导出的DataTable</param>
        /// <param name="FileType">类型</param>
        /// <param name="FileName">Excel的文件名</param>
        public static void ExportToExcel(DataTable dt, string FileType, string FileName, Func<string, string> fColumnText, Func<string, bool> fHidden, Func<string,object,string> fText)
        {
            HttpResponse Response = HttpContext.Current.Response;

            Response.Clear();
            Response.Charset = "UTF-8";
            Response.Buffer = true;
            Response.ContentEncoding = System.Text.Encoding.Default;  //.GetEncoding("GB2312");
            Response.AppendHeader("Content-Disposition", "attachment;filename=\"" + System.Web.HttpUtility.UrlEncode(FileName, System.Text.Encoding.UTF8) + ".xls\"");
            Response.ContentType = FileType;

            StringBuilder sb = new StringBuilder();
            DataRow[] myRow = dt.Select();
            int i = 0;
            int cl = dt.Columns.Count;
            foreach (DataColumn column in dt.Columns)
            {
                if (!fHidden(column.ColumnName))
                {
                    sb.Append(fColumnText(column.ColumnName) + "\t");
                }
            }
            sb.Append("\n");

            foreach (DataRow row in myRow)
            {
                foreach (DataColumn column in dt.Columns)
                {
                    if (!fHidden(column.ColumnName))
                    {
                        sb.Append(fText(column.ColumnName, row[column.ColumnName]) + "\t");
                    }
                }

                sb.Append("\n");
            }
            Response.Output.Write(sb.ToString());
            Response.Output.Flush();
            Response.End();
        }

        /// <summary>
        /// 返回去掉所有空格的字符串
        /// </summary>
        /// <param name="text"></param>
        /// <returns></returns>
        public static string ReturnString(string text)
        {
            string value = string.Empty;
            CharEnumerator CEnumerator = text.GetEnumerator();

            while (CEnumerator.MoveNext())
            {

                byte[] array = new byte[1];

                array = System.Text.Encoding.ASCII.GetBytes(CEnumerator.Current.ToString());

                int asciicode = (short)(array[0]);

                if (asciicode != 32)
                {

                    value += CEnumerator.Current.ToString();

                }

            }
            return value;
        }

        public static string fileUpLoad(HttpPostedFile file, string filePackage = "")
        {
            string savePath = "";
            if ((file != null && file.ContentLength > 0))
            {
                string fileExtension = Path.GetExtension(file.FileName).ToLower();
                if (ext.Contains(fileExtension))
                {
                    string filename = DateTime.Now.Ticks + Path.GetExtension(file.FileName);
                    string dir = "/UpLoad/" + (string.IsNullOrEmpty(filePackage) ? "" : filePackage + "/") + DateTime.Now.ToString("yyyy/MM/dd/");
                    string fullDir = System.Web.HttpContext.Current.Server.MapPath(dir);
                    if (!Directory.Exists(fullDir))
                    {
                        Directory.CreateDirectory(fullDir);
                    }
                    file.SaveAs(fullDir + filename);
                    savePath = dir + filename;
                }
                else
                {
                    savePath = "-1";
                }
            }
            return savePath;
        }

        public static string GetJson(DataRow dr)
        {
            StringBuilder jsonBuilder = new StringBuilder();
            DataTable dt = dr.Table;

            jsonBuilder.Append("{");
            for (int j = 0; j < dt.Columns.Count; j++)
            {
                jsonBuilder.Append("\"");
                jsonBuilder.Append(dt.Columns[j].ColumnName);
                jsonBuilder.Append("\":\"");
                jsonBuilder.Append(dr[j].ToString());
                jsonBuilder.Append("\",");
            }
            jsonBuilder.Remove(jsonBuilder.Length - 1, 1);
            jsonBuilder.Append("}");

            return jsonBuilder.ToString();
        }

        public static string ClearHTML(string Htmlstring)  //替换HTML标记
        {
            //删除脚本
            Htmlstring = Regex.Replace(Htmlstring, @"<script[^>]*?>.*?</script>", "", RegexOptions.IgnoreCase);

            //删除HTML
            Htmlstring = Regex.Replace(Htmlstring, @"<(.[^>]*)>", "", RegexOptions.IgnoreCase);
            Htmlstring = Regex.Replace(Htmlstring, @"([\r\n])[\s]+", "", RegexOptions.IgnoreCase);
            Htmlstring = Regex.Replace(Htmlstring, @"-->", "", RegexOptions.IgnoreCase);
            Htmlstring = Regex.Replace(Htmlstring, @"<!--.*", "", RegexOptions.IgnoreCase);
            Htmlstring = Regex.Replace(Htmlstring, @"&(quot|#34);", "\"", RegexOptions.IgnoreCase);
            Htmlstring = Regex.Replace(Htmlstring, @"&(amp|#38);", "&", RegexOptions.IgnoreCase);
            Htmlstring = Regex.Replace(Htmlstring, @"&(lt|#60);", "<", RegexOptions.IgnoreCase);
            Htmlstring = Regex.Replace(Htmlstring, @"&(gt|#62);", ">", RegexOptions.IgnoreCase);
            Htmlstring = Regex.Replace(Htmlstring, @"&(nbsp|#160);", " ", RegexOptions.IgnoreCase);
            Htmlstring = Regex.Replace(Htmlstring, @"&(iexcl|#161);", "\xa1", RegexOptions.IgnoreCase);
            Htmlstring = Regex.Replace(Htmlstring, @"&(cent|#162);", "\xa2", RegexOptions.IgnoreCase);
            Htmlstring = Regex.Replace(Htmlstring, @"&(pound|#163);", "\xa3", RegexOptions.IgnoreCase);
            Htmlstring = Regex.Replace(Htmlstring, @"&(copy|#169);", "\xa9", RegexOptions.IgnoreCase);
            Htmlstring = Regex.Replace(Htmlstring, @"&#(\d+);", "", RegexOptions.IgnoreCase);
            Htmlstring = Regex.Replace(Htmlstring, @"<img[^>]*>;", "", RegexOptions.IgnoreCase);
            Htmlstring.Replace("<", "");
            Htmlstring.Replace(">", "");
            Htmlstring.Replace("\r\n", "");
            Htmlstring = HttpContext.Current.Server.HtmlEncode(Htmlstring).Trim();
            return Htmlstring;
        }

        /// <summary>
        /// 获得新闻简介
        /// </summary>
        /// <param name="news"></param>
        /// <param name="length"></param>
        /// <returns></returns>
        public static string GetNewsIntro(string news, int length = 80)
        {
            if (string.IsNullOrEmpty(news)) return string.Empty;

            return GetSubString(ClearHTML(news), length, "...");
        }

        public static string GetXmlNode(XmlDocument doc, string xpath)
        {
            var node = doc.SelectSingleNode(xpath);
            return node == null ? string.Empty : node.InnerText;
        }
    }
}
